The objective of this assignment is to build a machine learning Cat/Dog image classifier.Given dataset consists of 1000 images for traing the model and another 100 images where the model is applied to predict whether the image is of a cat or dog.
# Load all required libraries
import cv2
from PIL import Image
import numpy as np
import matplotlib.pyplot as plt
import matplotlib. image as matImage
from os import listdir
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import normalize
from sklearn.neighbors import KNeighborsClassifier
from sklearn.svm import SVC
from sklearn.naive_bayes import GaussianNB
import pandas as pd
from sklearn.model_selection import GridSearchCV
from sklearn.linear_model import LogisticRegression
import warnings
warnings.filterwarnings('ignore')
from sklearn.decomposition import PCA
# Load Training data
sourceDir = "./data/train/"
# list to store the training images
X_train = list()
# list to store the training labels
Y_train = list()
# list to store the validation images
X_dev = list()
# list to store the validation labels
Y_dev = list()
#This loop iterates each image present in the source directory.
# Read image using openCV library and convert all images to common size 250x250
for fileName in listdir(sourceDir):
image_l = cv2.imread(sourceDir+fileName)
image_l = cv2.resize(image_l, (250, 250))
X_train.append(image_l)
# image name format is cat.1, So extracting the labels from image name
name = fileName.split('.')
if (name[0] == "cat"):
Y_train.append(0)
else:
Y_train.append(1)
# Verify training images
X_train = np.array(X_train)
# Reshape the image data into rows
X_train = np.reshape(X_train, (X_train.shape[0], -1))
Y_train = np.array(Y_train)
## Normalise Data
X_train = normalize(X_train,norm = 'max')
# 80% for training and 20% for validation
X_train, X_dev, Y_train, Y_dev = train_test_split(X_train,Y_train, test_size=0.20, random_state=42 )
_,ax = plt.subplots(5,6, figsize=(30,30))
for i in range(5):
for j in range(6):
ax[i,j].imshow(cv2.cvtColor(X_train[100+(i*100)+j], cv2.COLOR_BGR2RGB))
ax[i,j].axis('off')
plt.show()
# create a dataframe to store details of each algorithms tried
data = {'modelName':["KNN","NB","LR"],
'modelObject':[KNeighborsClassifier(n_neighbors=1, n_jobs=-1),GaussianNB(),LogisticRegression(solver = "lbfgs")],
'accuracy':[None,None,None]}
modelDetails =pd.DataFrame(data,columns=['modelName','modelObject','accuracy'])
index = 0
# train 3 models and save its accuracy
for model in modelDetails['modelObject']:
model_fit = model.fit(X_train, Y_train)
acc = model_fit.score(X_dev, Y_dev)
modelDetails.iloc[index,2] = acc
index= index+1
print(modelDetails[['modelName', 'accuracy']])
pca_dims = PCA()
pca_dims.fit(X_train)
cumsum = np.cumsum(pca_dims.explained_variance_ratio_)
d = np.argmax(cumsum >= 0.90) + 1
d
pca = PCA(n_components=d)
X_reduced = pca.fit_transform(X_train)
X_recovered = pca.inverse_transform(X_reduced)
print("reduced shape: " + str(X_reduced.shape))
print("recovered shape: " + str(X_recovered.shape))
data = {'modelName':["KNN","NB","LR"],
'modelObject':[KNeighborsClassifier(n_neighbors=1, n_jobs=-1),GaussianNB(),LogisticRegression(solver = "lbfgs")],
'accuracy':[None,None,None]}
modelDetails =pd.DataFrame(data,columns=['modelName','modelObject','accuracy'])
index = 0
# train 3 models and save its accuracy
for model in modelDetails['modelObject']:
model_fit = model.fit(X_reduced, Y_train)
# transform the validation set
X_dev_reduced = pca.fit_transform(X_dev)
acc = model_fit.score(X_dev_reduced, Y_dev)
modelDetails.iloc[index,2] = acc
index= index+1
print(modelDetails[['modelName', 'accuracy']])
# Train a LR model
model_LR = LogisticRegression(solver = "lbfgs")
model_LR.fit(X_train, Y_train)
sourceDir = "./data/test/"
X_test_pre = list()
# iterate over test image and create list of images in correct shape
for fileName in listdir(sourceDir):
image_test = cv2.imread(sourceDir+fileName)
image_test = cv2.resize(image_test, (250, 250))
X_test_pre.append(image_test)
X_test = np.stack(X_test_pre, axis=0)
X_test = np.reshape(X_test, (X_test.shape[0], -1))
# using the best model, classify dog and cat images.
dists = model_LR.predict(X_test)
print(dists)
unique, counts = np.unique(dists, return_counts=True)
dict(zip(unique, counts))
_,ax = plt.subplots(5,6, figsize=(30,30))
for i in range(5):
for j in range(6):
ax[i,j].imshow(cv2.cvtColor(X_test_pre[10+(i*2)+j], cv2.COLOR_BGR2RGB))
ax[i,j].axis('off')
if(dists[10+(i*2)+j] == 0):
ax[i,j].set_title("cat")
else:
ax[i,j].set_title("dog")
plt.show()
# hyperparameter optimization on the final model
param_grid = {'C': [0.001, 0.01, 0.1, 1, 10, 100],
"penalty":["l1","l2"]}
model_tuned_LR = LogisticRegression()
grid_search = GridSearchCV(
model_tuned_LR, param_grid, cv=10, scoring='accuracy')
grid_search.fit(X_reduced, Y_train)
bestLR = grid_search.best_estimator_ # choose the best estimator
print("grid search best score :",grid_search.best_score_)
print("LR best params",grid_search.best_params_)
#train model on best estimator
bestLR.fit(X_reduced, Y_train)
acc = bestLR.score(X_dev_reduced,Y_dev)
print(acc)